import { useState, useCallback } from 'react';

interface ValidationRules {
  required?: boolean;
  minLength?: number;
  maxLength?: number;
  pattern?: RegExp;
  customValidator?: (value: any) => string | null;
}

interface FormField {
  value: any;
  error: string | null;
}

export const useFormValidation = <T extends Record<string, any>>(initialValues: T) => {
  const [fields, setFields] = useState<Record<keyof T, FormField>>(
    Object.keys(initialValues).reduce((acc, key) => {
      acc[key as keyof T] = { value: initialValues[key], error: null };
      return acc;
    }, {} as Record<keyof T, FormField>)
  );

  const validateField = useCallback((
    name: keyof T,
    value: any,
    rules: ValidationRules
  ): string | null => {
    if (rules.required && (value === null || value === undefined || value === '')) {
      return '此字段为必填项';
    }

    if (rules.minLength && value && value.length < rules.minLength) {
      return `最少需要${rules.minLength}个字符`;
    }

    if (rules.maxLength && value && value.length > rules.maxLength) {
      return `最多允许${rules.maxLength}个字符`;
    }

    if (rules.pattern && value && !rules.pattern.test(value)) {
      return '格式不正确';
    }

    if (rules.customValidator) {
      return rules.customValidator(value);
    }

    return null;
  }, []);

  const setFieldValue = useCallback((
    name: keyof T,
    value: any,
    rules?: ValidationRules
  ) => {
    setFields(prev => ({
      ...prev,
      [name]: {
        value,
        error: rules ? validateField(name, value, rules) : null
      }
    }));
  }, [validateField]);

  const validateForm = useCallback((
    validationRules: Record<keyof T, ValidationRules>
  ): boolean => {
    let isValid = true;
    const newFields = { ...fields };

    Object.keys(validationRules).forEach(key => {
      const name = key as keyof T;
      const rules = validationRules[name];
      const error = validateField(name, fields[name].value, rules);
      
      if (error) {
        isValid = false;
      }
      
      newFields[name] = {
        value: fields[name].value,
        error
      };
    });

    setFields(newFields as Record<keyof T, FormField>);
    return isValid;
  }, [fields, validateField]);

  const resetForm = useCallback(() => {
    setFields(
      Object.keys(initialValues).reduce((acc, key) => {
        acc[key as keyof T] = { value: initialValues[key], error: null };
        return acc;
      }, {} as Record<keyof T, FormField>)
    );
  }, [initialValues]);

  return {
    fields,
    setFieldValue,
    validateForm,
    resetForm,
    isValid: Object.values(fields).every(field => !field.error)
  };
};